/**
*  \file can.c
*
*  \brief
*
*  \author Michael J. Hohmann  <michael.hohmann@linde-mh.de>
*
*
*/

/*===============================================[ private includes  ]================================================*/
#include "can.h"
#include "../assertor/assertor.h"
#include "../cancom/cancom.h"
#include "../cansim/cansim.h"
#include "../cant/cant.h"


/*===============================================[ private defines   ]================================================*/
#define CAN_A_TABLE_SIZE 32
#define CAN_B_TABLE_SIZE 32
#define CAN_C_TABLE_SIZE 32

/*===============================================[ private datatypes ]================================================*/


/** Private variables */
struct can_private
{
   struct candispatcher_obj dispatcher[3];
   struct candispatcher_entry a_table[ CAN_A_TABLE_SIZE ];
   struct candispatcher_entry b_table[ CAN_B_TABLE_SIZE ];
   struct candispatcher_entry c_table[ CAN_B_TABLE_SIZE ];
   struct cant_obj can[3]; /**<  */

};

/*===============================================[ private variables ]================================================*/
static struct can_private can;


/*===============================================[ private functions ]================================================*/
static void can_msg_default(struct cant_obj * me, struct canmsg* msg, void *data );

/*===============================================[ inline functions  ]================================================*/

/*===============================================[ public functions  ]================================================*/
RC can_initialize( void )
{
	pal_memzero( &can, sizeof can);

	if( RC_SUCCESS != cant_construct( &can.can[can_channel_int], U32_CONST(500000),"kcpc_can_int", 0 ) )
	{
		return RC_ERROR;
	}
	cant_install_default_rx_callback(&can.can[can_channel_int], can_msg_default, (void*)can_channel_int  );


	if( RC_SUCCESS != cant_construct( &can.can[can_channel_ext], U32_CONST(500000),"kcpc_can_ext", 0) )
	{
		return RC_ERROR;
	}
	cant_install_default_rx_callback(&can.can[can_channel_ext], can_msg_default, (void*)can_channel_ext  );

	if( RC_SUCCESS != cant_construct( &can.can[can_channel_sim], U32_CONST(500000),"kcpc_can_sim", 0 ) )
	{
		return RC_ERROR;
	}
	cant_install_default_rx_callback(&can.can[can_channel_sim], can_msg_default, (void*)can_channel_sim );


	candispatcher_construct( &can.dispatcher[0], can.a_table, CAN_A_TABLE_SIZE );
	candispatcher_construct( &can.dispatcher[1], can.b_table, CAN_B_TABLE_SIZE );
	candispatcher_construct( &can.dispatcher[2], can.c_table, CAN_C_TABLE_SIZE );
	cansim_initialize();
	candispatcher_enable(  &can.dispatcher[0], TRUE);
	candispatcher_enable(  &can.dispatcher[1], TRUE);
	candispatcher_enable(  &can.dispatcher[2], TRUE);

	//cancom_initialize();

   return RC_SUCCESS;
}


/* Send can message on the bus.
*
*
*
*  \param channel will not be used in MMU project
*
*/
void can_install_rx_callback( U8 channel,canmsg_id_t id, can_callback_function_t callback, void* data )
{
   UNREFERENCED( channel );
   candispatcher_install_callback( &can.dispatcher[channel], id,callback , data );
}

/* Send can message on the bus.
*
*
*  \param msg pointer to the message
*  \param channel will not be used in MMU project
*
*/
void can_tx_msg(enum can_channel channel, struct canmsg *msg)
{
   cant_tx(&can.can[channel], msg );

}

void can_tx( enum can_channel channel, U32 id, void const* data, U8 len )
{
	struct canmsg msg;
	pal_memcpy(canmsg_set(&msg,id,len),data,len);
	can_tx_msg(channel, &msg );
}



/* this function is contained in the interface
 * it is for you to receive a can message from an interrupt
 *
 */
void can_process_message(U8 channel, struct canmsg *msg)
{
   candispatcher_dispatch_message( &can.dispatcher[channel], msg);
}

/*===============================================[ private functions ]================================================*/


static void can_msg_default(struct cant_obj * me, struct canmsg* msg, void *data )
{
   UNREFERENCED( data );
   UNREFERENCED( me   );
   can_process_message((U32)data, msg);
}






/***********************************************************************************************************************
*                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
